package org.deadline.model.config;

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.deadline.model.baseapp.OrganizationDataOnDemand;
import org.deadline.model.user.Person;
import org.deadline.repository.config.LdapServerRepository;
import org.deadline.service.config.LdapServerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Component;

@Component
@Configurable
public class LdapServerDataOnDemand {

	private Random rnd = new SecureRandom();

	private List<LdapServer> data;

	@Autowired
    private OrganizationDataOnDemand organizationDataOnDemand;

	@Autowired
    private EnumerationDataOnDemand enumerationDataOnDemand;

	@Autowired
    LdapServerService ldapServerService;

	@Autowired
    LdapServerRepository ldapServerRepository;

	public LdapServer getNewTransientLdapServer(int index) {
        LdapServer obj = new LdapServer();
        setBase(obj, index);
        setCreationDate(obj, index);
        setDeleted(obj, index);
        setDomainName(obj, index);
        setEmailSearchBase(obj, index);
        setEnabled(obj, index);
        setModificationDate(obj, index);
        setOwner(obj, index);
        setPassword(obj, index);
        setUrl(obj, index);
        setUserDn(obj, index);
        setUserSearchBase(obj, index);
        setUserSearchFilter(obj, index);
        return obj;
    }

	public void setBase(LdapServer obj, int index) {
        String base = "base_" + index;
        if (base.length() > 255) {
            base = base.substring(0, 255);
        }
        obj.setBase(base);
    }

	public void setCreationDate(LdapServer obj, int index) {
        Date creationDate = new GregorianCalendar(Calendar.getInstance().get(Calendar.YEAR), Calendar.getInstance().get(Calendar.MONTH), Calendar.getInstance().get(Calendar.DAY_OF_MONTH), Calendar.getInstance().get(Calendar.HOUR_OF_DAY), Calendar.getInstance().get(Calendar.MINUTE), Calendar.getInstance().get(Calendar.SECOND) + new Double(Math.random() * 1000).intValue()).getTime();
        obj.setCreationDate(creationDate);
    }

	public void setDeleted(LdapServer obj, int index) {
        Boolean deleted = true;
        obj.setDeleted(deleted);
    }

	public void setDomainName(LdapServer obj, int index) {
        String domainName = "domainName_" + index;
        if (domainName.length() > 255) {
            domainName = new Random().nextInt(10) + domainName.substring(1, 255);
        }
        obj.setDomainName(domainName);
    }

	public void setEmailSearchBase(LdapServer obj, int index) {
        String emailSearchBase = "foo" + index + "@bar.com";
        if (emailSearchBase.length() > 255) {
            emailSearchBase = emailSearchBase.substring(0, 255);
        }
        obj.setEmailSearchBase(emailSearchBase);
    }

	public void setEnabled(LdapServer obj, int index) {
        Boolean enabled = true;
        obj.setEnabled(enabled);
    }

	public void setModificationDate(LdapServer obj, int index) {
        Date modificationDate = new GregorianCalendar(Calendar.getInstance().get(Calendar.YEAR), Calendar.getInstance().get(Calendar.MONTH), Calendar.getInstance().get(Calendar.DAY_OF_MONTH), Calendar.getInstance().get(Calendar.HOUR_OF_DAY), Calendar.getInstance().get(Calendar.MINUTE), Calendar.getInstance().get(Calendar.SECOND) + new Double(Math.random() * 1000).intValue()).getTime();
        obj.setModificationDate(modificationDate);
    }

	public void setOwner(LdapServer obj, int index) {
        Person owner = null;
        obj.setOwner(owner);
    }

	public void setPassword(LdapServer obj, int index) {
        String password = "password_" + index;
        if (password.length() > 100) {
            password = password.substring(0, 100);
        }
        obj.setPassword(password);
    }

	public void setUrl(LdapServer obj, int index) {
        String url = "url_" + index;
        if (url.length() > 255) {
            url = url.substring(0, 255);
        }
        obj.setUrl(url);
    }

	public void setUserDn(LdapServer obj, int index) {
        String userDn = "userDn_" + index;
        if (userDn.length() > 255) {
            userDn = userDn.substring(0, 255);
        }
        obj.setUserDn(userDn);
    }

	public void setUserSearchBase(LdapServer obj, int index) {
        String userSearchBase = "userSearchBase_" + index;
        if (userSearchBase.length() > 255) {
            userSearchBase = userSearchBase.substring(0, 255);
        }
        obj.setUserSearchBase(userSearchBase);
    }

	public void setUserSearchFilter(LdapServer obj, int index) {
        String userSearchFilter = "userSearchFilter_" + index;
        if (userSearchFilter.length() > 255) {
            userSearchFilter = userSearchFilter.substring(0, 255);
        }
        obj.setUserSearchFilter(userSearchFilter);
    }

	public LdapServer getSpecificLdapServer(int index) {
        init();
        if (index < 0) {
            index = 0;
        }
        if (index > (data.size() - 1)) {
            index = data.size() - 1;
        }
        LdapServer obj = data.get(index);
        Long id = obj.getId();
        return ldapServerService.findLdapServer(id);
    }

	public LdapServer getRandomLdapServer() {
        init();
        LdapServer obj = data.get(rnd.nextInt(data.size()));
        Long id = obj.getId();
        return ldapServerService.findLdapServer(id);
    }

	public boolean modifyLdapServer(LdapServer obj) {
        return false;
    }

	public void init() {
        int from = 0;
        int to = 10;
        data = ldapServerService.findLdapServerEntries(from, to);
        if (data == null) {
            throw new IllegalStateException("Find entries implementation for 'LdapServer' illegally returned null");
        }
        if (!data.isEmpty()) {
            return;
        }
        
        data = new ArrayList<LdapServer>();
        for (int i = 0; i < 10; i++) {
            LdapServer obj = getNewTransientLdapServer(i);
            try {
                ldapServerService.saveLdapServer(obj);
            } catch (ConstraintViolationException e) {
                StringBuilder msg = new StringBuilder();
                for (Iterator<ConstraintViolation<?>> iter = e.getConstraintViolations().iterator(); iter.hasNext();) {
                    ConstraintViolation<?> cv = iter.next();
                    msg.append("[").append(cv.getConstraintDescriptor()).append(":").append(cv.getMessage()).append("=").append(cv.getInvalidValue()).append("]");
                }
                throw new RuntimeException(msg.toString(), e);
            }
            ldapServerRepository.flush();
            data.add(obj);
        }
    }
}
